package org.teamh.gui.ingame.data_structure;

public class SafeList<E> {

	private Element<E> head;
	
	public Element<E> getHead() {
		return head;
	}
	
	public boolean add(String name, E e) {
		if(head == null) {
			head = new Element<E>(name, e);
			return true;
		}
		
		Element<E> next = head;
		
		while(next.getNext() != null) {
			if(!next.getName().equals(name)) {
				next = next.getNext();
			} else {
				return false;
			}
		}
		
		Element<E> newElement = new Element<E>(name, e);
		next.setNext(newElement);
		
		return true;
	}
	
	public boolean remove(String name) {
		Element<E> next = head;
		
		while(next != null) {
			if(next.getName().equals(name)) {
				if(next == head) {
					head = next.getNext();
				}
				if(next.getPrevious() != null) {
					next.getPrevious().setNext(next.getNext());
				} else {
					if(next.getNext() != null) {
						next.getNext().setPrevious(next.getPrevious());
					}
				}
				return true;
			}
			next = next.getNext();
		}
		
		return false;
	}
	
	public boolean remove(E e) {
		Element<E> next = head;
		
		while(next != null) {
			if(next.getE() == e) {
				if(next == head && next.getNext() != null) {
					head = next.getNext();
				}
				if(next.getPrevious() != null) {
					next.getPrevious().setNext(next.getNext());
				}
				if(next.getNext() != null) {
					next.getNext().setPrevious(next.getPrevious());
				}
				return true;
			}
			next.getNext();
		}
		
		return false;
	}
	
	public E get(String name) {
		Element<E> next = head;
		
		while(next != null) {
			if(next.getName().equals(name)) {
				return next.getE();
			}
			
			next = next.getNext();
		}
		
		return null;
	}
	
	public static class Element<E> {
		private String name;
		private E e;
		private Element<E> next;
		private Element<E> previous;
		
		public Element(String name, E e) {
			this.name = name;
			this.e = e;
		}
		
		public String getName() {
			return name;
		}
		
		public E getE() {
			return e;
		}
		
		public Element<E> getNext() {
			return next;
		}
		
		public void setNext(Element<E> next) {
			if(this.next != next) {
				if(getNext() != null) {
					Element<E> oldNext = getNext();
					this.next = null;
					oldNext.setPrevious(null);
				}
				this.next = next;
				if(getNext() != null) {
					getNext().setPrevious(this);
				}
			}
		}
		
		public void setPrevious(Element<E> previous) {
			if(this.previous != previous) {
				if(getPrevious() != null) {
					Element<E> oldPrevious = getPrevious();
					this.previous = null;
					oldPrevious.setNext(null);
				}
				this.previous = previous;
				if(getPrevious() != null) {
					getPrevious().setNext(this);
				}
			}
		}
		
		public Element<E> getPrevious() {
			return previous;
		}
	}
	
	public void clear() {
		Element<E> next = head;
		
		if(head == null) {
			return;
		}
		while(next.getNext() != null) {
			next.setPrevious(null);
			next = next.getNext();
		}
		
		head = null;
	}
	
	public int size() {
		int size = 0;
		Element<E> next = head;
		
		while(next != null) {
			size++;
			next = next.getNext();
		}
		return size;
	}
}
